package cn.wj.school.cloud.controller;

import cn.wj.school.cloud.dto.DWZResult;
import cn.wj.school.cloud.dto.PageResponse;
import cn.wj.school.cloud.dto.SyLoginLogDTO;
import cn.wj.school.cloud.dto.SyUserDTO;
import cn.wj.school.cloud.dto.condition.LoginLogCondition;
import cn.wj.school.cloud.dto.condition.UserCondition;
import cn.wj.school.cloud.enums.UserType;
import cn.wj.school.cloud.exception.ServiceInvokeException;
import cn.wj.school.cloud.model.SyLoginLog;
import cn.wj.school.cloud.security.SecurityAuthentication;
import cn.wj.school.cloud.security.SecurityContextHolder;
import cn.wj.school.cloud.security.context.SecurityContext;
import cn.wj.school.cloud.service.LoginLogService;
import cn.wj.school.cloud.service.UserService;
import cn.wj.school.cloud.utils.EncryptAlgorithm;
import cn.wj.school.cloud.utils.SecurityUtils;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @Author: yueding
 * @Description: 登录控制下
 * @Date: Created in 13:54 2019/1/8
 * @Modified By: yueding Copyright(c) cai-inc.com
 */
@Controller
@RequestMapping("/*")
public class LoginController extends BaseController {
    @Resource
    private UserService userService;

    @Resource
    private LoginLogService loginLogService;

    @RequestMapping(value = "login", method = RequestMethod.GET)
    public String login() {
        return "login";
    }

    @RequestMapping(value = "*")
    public String index(Model model) {

        model.addAttribute("userInfo", SecurityUtils.getCurrentUser());

        return "index";
    }

    @RequestMapping(value = "doLogin", method = RequestMethod.POST)
    public String doLogin(Model model, String userCode, String password, HttpServletRequest request) {

        SyUserDTO user = userService.getUserByUserAccount(userCode);
        if (null != user && EncryptAlgorithm.hexMD5(password).equals(user.getPassword())) {
            SecurityAuthentication authentication = new SecurityAuthentication(user.getCard(), user);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            HttpSession session = request.getSession(false);
            Map attributesToMigrate = Maps.newHashMap();
            if(session != null){
                attributesToMigrate.putAll(this.createMigratedAttributeMap(session));
                session.invalidate();
            }
            //登录成功重新生成session
            session = request.getSession(true);
            session.setAttribute(SecurityContextHolder.SECURITY_CONTEXT, SecurityContextHolder.getContext());
            this.transferAttributes(attributesToMigrate, session);
            return "redirect:/index";
        }
        model.addAttribute("message", "用户名或密码错误！");
        return "login";
    }

    @RequestMapping(value = "logout", method = RequestMethod.GET)
    public String logout(HttpServletRequest request) {
        // 移除session
        HttpSession session = request.getSession(false);
        if(session != null) {
            session.removeAttribute(SecurityContextHolder.SECURITY_CONTEXT);
            SecurityContext context = SecurityContextHolder.getContext();
            context.setAuthentication(null);
            SecurityContextHolder.clearContext();
            session.invalidate();
        }
        return "login";
    }

    @RequestMapping(value = "changePWD", method = RequestMethod.GET)
    public String changePWD() {

        return "changepwd";
    }

    @RequestMapping("savePwd")
    @ResponseBody
    public DWZResult savePwd(Model model, String navTabId, String password, String newPassword) {
        try {
            if (StringUtils.isEmpty(password) || StringUtils.isEmpty(newPassword)) {
                return ajaxError("密码不能为空!");
            }
            if (password.equals(newPassword)) {
                return ajaxError("新密码不能和旧密码一样!");
            }
            SyUserDTO u = userService.getUserByUserAccount(SecurityUtils.getCurrentUserCode());
            if (EncryptAlgorithm.hexMD5(password).equals(u.getPassword())) {
                userService.updateUserPwd(u.getId(), EncryptAlgorithm.hexMD5(newPassword));
                return dialogAjaxDone("操作成功", navTabId, null, null, null);
            } else {
                return ajaxError("旧密码输入不正确!");
            }
        } catch (Exception e) {
            LOGGER.error("{}", e);
            model.addAttribute("message", e.getMessage());
            return ajaxError("操作失败");
        }
    }

    /**
     * 获取登录日志列表
     * @param model
     * @param logCondition
     * @param navTabId
     * @return
     */
    @RequestMapping("login_log")
    public String logList(Model model, @ModelAttribute("condition") LoginLogCondition logCondition, String navTabId) {
        /**
         * 填充当前用户的角色
         */
        SyUserDTO loginUser = SecurityUtils.getCurrentUser();
        /**
         * 学校管理员可以看到学校的用户
         */
        Map<String, String> type = UserType.map;
        if (UserType.ADMIN.name().equals(loginUser.getType())) {
            logCondition.setSchool(SecurityUtils.getCurrentUser().getSchool());
            type.remove(UserType.ADMINISTRAOR);
        }
        PageResponse<SyLoginLogDTO> logs = loginLogService.getLoginLogsByCondition(logCondition);
        model.addAttribute("userType", type);
        model.addAttribute("page", logs);
        model.addAttribute(NAVTABID, navTabId);
        return "user/login_log";
    }

    private HashMap<String, Object> createMigratedAttributeMap(HttpSession session) {
        HashMap attributesToMigrate = new HashMap();
        Enumeration enumer = session.getAttributeNames();
        while (enumer.hasMoreElements()) {
            String key = (String)enumer.nextElement();
            attributesToMigrate.put(key, session.getAttribute(key));
        }
        return attributesToMigrate;
    }

    void transferAttributes(Map<String, Object> attributes, HttpSession newSession) {
        if(attributes != null) {
            Iterator var3 = attributes.entrySet().iterator();

            while(var3.hasNext()) {
                Map.Entry entry = (Map.Entry)var3.next();
                newSession.setAttribute((String)entry.getKey(), entry.getValue());
            }
        }

    }
}
